
//控制器 是个类

const {Controller}=require('egg');
const axios =require('axios');
const {
    REDIRECT_URI,
    CLIENT_ID,
    CLIENT_SECRET
}=require('../config');
const {
    userValidate,//引入校验规则
}=require('../config/userRule');
const fs=require('fs');
const path=require('path');

const newBuffer=new Map();//map对象

class UserController extends Controller{//继承 Controller

    async sendRole(){//发送角色列表
        const {ctx}=this;
        let teacherCount=await ctx.service.user.getRoleCount(1);
        let stuCount=await ctx.service.user.getRoleCount(2);
        let teach2Count=await ctx.service.user.getRoleCount(3);
        // console.log(Object.values(teacherCount[0]) ,stuCount,teach2Count)
        //重组数据，返回给前端
        ctx.body={
            code:1001,
            msg:"获取角色列表成功",
            result:[
                {
                    value:teacherCount.length,
                    name:"讲师",
                },
                {
                    value:stuCount.length,
                    name:"学生",
                },
                {
                    value:teach2Count.length,
                    name:"辅导员",
                }
            ]
        }

    }
    async sendMail(){//发送邮件
        let {ctx}=this;
        let {mail,username}=ctx.request.body;
        let pwdResult=await ctx.service.user.getPwd(username);//获取用户密码
        // console.log(pwdResult);
        if(pwdResult.length){
            let result=await ctx.helper.sendMail({
                title:'找回密码',
                html:`<h3>您的密码是：${pwdResult[0].pwd}</h3>`,
                mail
            });
            if(result.status==200){
                ctx.body={
                    code:1001,
                    msg:'邮箱发送成功'
                }
            }else{
                ctx.body={
                    code:1002,
                    msg:'邮箱发送失败'
                }
            }
        }else{
            ctx.body={
                code:1002,
                msg:'用户名输入错误，请重新输入'
            }
        }
     
    };
    async upload(){//上传图片
        let {ctx}=this;
        // console.log(ctx.request.query)
        let file=ctx.request.files[0];//获取前端上传文件信息
        let {id}=ctx.request.query;
        console.log(file);
        const name = 'images/' +new Date()*1 +path.basename(file.filename);//上传到oss上的文件夹名字
        let result;
        try {
            // 使用put方法 存储到oss中
          result = await ctx.oss.put(name, file.filepath);
        //   console.log(result);//上传到oss中返回的结果
        } finally {
            //删除临时文件
          await fs.unlinkSync(file.filepath);
        }
     
        if (result) {
            // console.log(result)
            if(result.res.status===200){
                // 把存储时候返回的路径存到数据库
                let addAvatar=await ctx.service.user.upload({id,avatar_url:result.url});
                if(addAvatar.affectedRows){
                    ctx.body={
                        code:1001,
                        msg:'avatar_url存储成功'
                    }
                }else{
                    ctx.body={
                        code:1002,
                        msg:'avatar_url存储失败'
                    }
                }
            }else{
                ctx.body = {
                    code:1002,
                    msg:'oss 存储失败'
                } 
            }
        } else {
          ctx.body = 'please select a file to upload！';
        }
    };
    async getUserInfoByAcessToken({access_token}){//获取用户信息
        let {ctx}=this;
        const result=await axios.get('https://gitee.com/api/v5/user',{params:{access_token}});
        if(result.status==200){
            let {login,name,avatar_url}=result.data;
            //判断用户名是否存在
            const flag=await ctx.service.user.checkUser(login);
            if(flag){//不存在
                //生成id 添加到数据库
                let id=ctx.helper.createId(login);
                let addResult=await ctx.service.user.addUserByAccessToken({//添加用户
                    id,login,name,avatar_url
                });
                console.log(addResult)
                if(addResult.affectedRows){
                    return {
                        code:1001,
                        msg:'第三方登录成功',
                        token:ctx.helper.createToken(id),
                        user_id:id
                    }
                }else{
                    return {
                       code:1002,
                       msg:'添加用户失败' 
                    }
                }
            }
            //如果用户存在
            // 返回token
            let checkResult=await ctx.service.user.getUserBylogin(login);
            let token=ctx.helper.createToken(checkResult[0].id);
                return{
                    code:1001,
                    msg:'第三方登录成功',
                    token,
                    user_id:checkResult[0].id
                }
        }else{
            return {
                code:1002,
                msg:"使用access_token获取用户信息失败"
            }
        }
    };
    async sendOauth(){//获取授权码
        let {ctx}=this;
        let {code}=ctx.request.query;
        // https://gitee.com/oauth/token?
        // grant_type=authorization_code&
        // code={code}&client_id={client_id}&
        // redirect_uri={redirect_uri}&
        // client_secret={client_secret}
        const result=await axios.post('https://gitee.com/oauth/token',{
            grant_type:'authorization_code',//使用授权码模式
            code,//授权码 只能使用一次
            redirect_uri:REDIRECT_URI,//回调地址
            client_id:CLIENT_ID,//应用id
            client_secret:CLIENT_SECRET,//应用密钥
        });//向第三方认证发送回调地址和授权码
        // console.log(result);
        if(result.status==200){
            //保存access_token 通过access_token获取用户信息
            //关联到数据库中
            // 通过access_token获取用户信息 保存到数据库
          ctx.body=await this.getUserInfoByAcessToken(result.data);
        }else{
            ctx.body={
                code:1002,
                msg:'获取access_token失败'
            }
        }
    };
    async userInfo(){//查询用户
        const {ctx}=this;
        console.log(ctx.request.query)
        const result=await ctx.service.user.userInfo(ctx.request.query);
        console.log(result);
        if(result.length){
            ctx.body={
                code:1001,
                msg:'查询用户成功',
                userInfo:result[0]
            }
        }else{
            ctx.body={
                code:1002,
                msg:'查询用户失败'
            }
          }
        
    };
    async editUser(){//编辑用户
        const {ctx}=this;
        console.log(ctx.request.body)
        const result=await ctx.service.user.editUser(ctx.request.body);
        console.log(result);
        if(result.affectedRows){
            ctx.body={
                code:1001,
                msg:'编辑成功'
            }
        }else{
            ctx.body={
                code:1002,
                msg:'编辑失败'
            }
          }
    };
    async del(){//删除用户
      const {ctx}=this; 
    //   console.log(ctx.params);
      const result=await ctx.service.user.del(ctx.params);
      console.log(result); 
      if(result.affectedRows){
          ctx.body={
              code:1001,
              msg:'删除成功'
          }
      }else{
        ctx.body={
            code:1002,
            msg:'删除失败'
        }
      }
    };
    async addUser(){//添加用户
        const {ctx}=this;
        const flag= await ctx.service.user.checkUsers(ctx.request.body);
        if(flag){//不存在
            const id=ctx.helper.createId();
            const result=await ctx.service.user.addusers({
                id,
                ...ctx.request.body
            });
            if(result.affectedRows){
                ctx.body={
                    code:1001,
                    msg:"添加成功"
                }
            }else{
                ctx.body={
                    code:1002,
                    msg:"添加失败"
                }
            }
        }else{
            ctx.body={
                code:1002,
                msg:'该用户已存在'
            }
        }
       
    };
    async getList(){
        console.log(1111111111111)
        const {ctx}=this;
        const {pageSize}=ctx.request.query;
        // console.log(ctx.request.query)
        // console.log(ctx.request.url)
    //    console.log(newBuffer)

        // map 对象的用法：
        // {
        //     '请求路径':{methods，数据库中查找出来的数据}
        // }
        // 使用map对象来缓存数据 buffer缓存部分操作

        //1.判断请求参数是否相同 和 响应的数据是否存在 如果存在，直接返回newBuffer的数据
        // 2.不存在或参数不同 把数据库中的数据存到newBuffer中 并返回
        const result= await ctx.service.user.getList(ctx.request.query);
        const count=await ctx.service.user.getCount(ctx.request.query);
        let bufferResult=newBuffer.get(ctx.request.url);
        console.log(result)
       
        // 请求路径作为键名 键值是请求方式 请求参数，请求需要返回的数据所组成的对象
        if(bufferResult){//判断是否有数据
           
            console.log(222222222)
            if(pageSize===bufferResult.pageSize&&bufferResult.result){//判断请求参数是否相同 和 响应的数据是否存在 如果存在，直接返回newBuffer的数据
                // console.log(bufferResult,4444)
                ctx.body={
                    code:1001,
                    msg:'获取数据成功',
                    result:result||bufferResult.result,
                    count:count||bufferResult.count
                }
            }else{//不存在或参数不同  把数据库中的数据存到newBuffer中并返回
                const result=await ctx.service.user.getList(ctx.request.query);
                const count=await ctx.service.user.getCount();
                // console.log(count)
                const obj={
                    pageSize,
                    result,
                    count
                };
                newBuffer.set(ctx.request.url,obj);//把数据库中的数据存到newBuffer中,请求路径作为键名
                if(result.length){
                    ctx.body={
                        code:1001,
                        msg:'获取用户列表成功',
                        result:newBuffer.get(ctx.request.url).result,//返回newBuffer中的数据
                        count:newBuffer.get(ctx.request.url).count,//总条数
                    }
                }else{
                    ctx.body={
                        code:1002,
                        msg:'暂无数据'
                    }
                }
            }
        }else{//如果bufferResult没有缓存数据
            console.log(333333333333);//问题：无法实时更新
            const result= await ctx.service.user.getList(ctx.request.query);
            console.log(result);
            const count=await ctx.service.user.getCount(ctx.request.query);
                const obj={
                    pageSize,
                    result,
                    count
                };
            newBuffer.set(ctx.request.url,obj);//把数据库中的数据存到newBuffer中
                if(result.length){
                    ctx.body={
                        code:1001,
                        msg:'获取用户列表成功',
                        result:result||newBuffer.get(ctx.request.url).result,
                        count:count||newBuffer.get(ctx.request.url).count,//总条数
                    }
                }else{
                    ctx.body={
                        code:1002,
                        msg:'暂无数据'
                    }
                }
        }
        

       
    };
    async login(){
        //this指的是当前项目的app应用
        // console.log(this);
        //ctx 是context上下文对象
        const{ctx}=this;
        // ctx.request.query; get 请求获取参数
        // ctx.request.body; post 请求获取参数
        //调用service 通过ctx.service.文件名.方法名 查询数据库

        // app 文件名 validate() 参数：1校验规则 2.传过来的参数 
        let error=ctx.app.validator.validate(userValidate,ctx.request.body);//错误信息
        console.log(error,66)
        if(error){
            ctx.status=406;
            ctx.body={
                code:1002,
                msg:'缺少必要的参数或者参数输入错误',
                error
            }
            return;//调出控制器，不走底下的代码
        }
        let {code}=ctx.request.body;

        if(ctx.session.text.toLowerCase()==code.toLowerCase()){//相等就调用service判断用户是否正确
            const result=await ctx.service.user.login(ctx.request.body);
            // console.log(result)
            if(result.length){
                // 登录成功，发送token
                const token=ctx.helper.createToken(result[0].id);
                ctx.body={
                    code:1001,
                    msg:'登录成功',
                    user_id:result[0].id,
                    token,
                    avatar_url:result[0].avatar_url
                }
            }else{
                ctx.body={
                    code:1002,
                    msg:'登录失败'
                }
            }
        }else{
            ctx.body={
                code:1002,
                msg:'验证码输入有误'
            }
        }
     
    };
    async sendCode(){//验证码
        const {ctx}=this;
        //调用扩展 ctx.helper.方法名()
        const result=await ctx.helper.createCode();
        if(result){
            //保存到session中，egg-session
            ctx.session.text=result.text;

            ctx.body={
                code:1001,
                msg:'获取验证码成功',
                result
            }
        }else{
            ctx.body={
                code:1002,
                msg:'获取验证码失败'
            }
        }
};
    async registry(){//注册
        const {ctx}=this;
        const {username}=ctx.request.body;
        //校验用户名是否已被注册
        const flag=await ctx.service.user.checkUser(username);
        if(flag){//不存在
            // 生成id
            const id=ctx.helper.createId(username);
            //调用service 注册的用户插入数据库中
            const result=await ctx.service.user.registry({
                id,
                ...ctx.request.body
            });
            if(result.affectedRows){
                ctx.body={
                    code:1001,
                    msg:'注册成功'
                }
            }else{
                ctx.body={
                    code:1002,
                    msg:'注册失败'
                }
            }

        }else{//存在
            ctx.body={
                code:1002,
                msg:'该用户已存在，重新注册'
            }
        }
    }
}
module.exports=UserController
